package cn.slg.module.system.service.pk.utils;

import cn.slg.module.system.dal.dataobject.wujiang.WuJiangDO;
import cn.slg.module.system.service.pk.skill.SKillCount;

// 伤兵和治疗体系
public class DieAndRescue {

    /**
     * 每回合开始、战斗结束，执行伤兵和死兵机制
     *
     * @param self
     * @param isEnd 是否是战斗结束
     */
    public static void die(WuJiangDO self, boolean isEnd, boolean fail) {
        if (!isEnd) {
            // 每回合，伤兵的10%变成死兵，即只保留90%的伤兵。
            System.out.println(self.getName() + "回合初伤兵变死兵");
            int die = (int) (self.getTotalWounded() * 0.1);
            self.setTotalWounded(self.getTotalWounded() - die);
            self.setTotalDie(self.getTotalDie() + die);
        } else {
            // 战斗结束后，已有伤兵的 30%会死亡，即只保留70%的伤兵。
            System.out.println(self.getName() + "战斗结束，伤兵变死兵");
            int die = (int) (self.getTotalWounded() * 0.3);
            self.setTotalWounded(self.getTotalWounded() - die);
            self.setTotalDie(self.getTotalDie() + die);

            // 如果己方队伍战败，自己没有死，且自身是副将，则其兵力的10%直接变成死兵
            if (fail && !self.getIsDie() && (!self.equals(self.getTeammates().getMain()))) {
                System.out.println("主将战死，" + self.getName() + "身为副将没有死，10%的兵力直接变死兵");
                short toDie = (short) (self.getBingLi() * 0.1);
                self.setBingLi((short) (self.getBingLi() - toDie));
                self.setTotalLoss(self.getTotalLoss() + toDie); // 也算损失
                self.setTotalDie(self.getTotalDie() + toDie);
            }

            // TODO 将伤兵累加到  累计伤兵
            self.setAccumWounded(self.getAccumWounded() + self.getTotalWounded());
            // TODO 战斗信息显示完毕后，要把伤兵清空，避免带到下一场战斗。
        }
    }

    /**
     * 受到伤害后，基于伤害扣除目标兵力，并将伤害的 90% 转化为伤兵，伤害的 10% 直接变死兵
     *
     * @param target 受到伤害的目标
     * @param harm   伤害值
     */
    public static void harmProcess(WuJiangDO target, Short harm) {
        // 扣除目标的兵力
        target.setBingLi((short) (target.getBingLi() - harm));

        // 累计目标的损失
        target.setTotalLoss(target.getTotalLoss() + harm);

        // 计算应该产生的伤兵数
        int wounded = (int) (0.9 * harm);

        // 伤害的 90% 转化为伤兵
        target.setTotalWounded(target.getTotalWounded() + wounded);

        // 伤害的 10% 直接变死兵
        target.setTotalDie(target.getTotalDie() + (harm - wounded));
    }


    // 回复兵力

    /**
     * @param isAffectByPv 该救援效果是否受到属性影响
     * @param rescuer      施加救援者
     * @param isRescuer    被救援者
     * @param rate         面板回复率
     * @param skillName    施加该治疗效果的技能名
     */
    public static Short rescue(boolean isAffectByPv, WuJiangDO rescuer, WuJiangDO isRescuer, Float rate, String skillName) {
        // TODO 判断 isRescuer（被救援者）是否处于禁疗状态

        // y = 135.83ln(被救援者自身兵力) - 815.84
        double byBingLi = 135.83 * Math.log(isRescuer.getBingLi()) - 815.84;

        Float pvZhiLi = 0f;
        if (isAffectByPv) {
            // 如果回复效果受到智力属性影响
            pvZhiLi = rescuer.getPvZhiLi();
        }
        // 能够治疗的数据
        short canRescue = (short) ((byBingLi + pvZhiLi) * rate);
        // 在被救援者剩余伤兵数和能够治疗数之间，取较小值
        canRescue = (short) Math.min(isRescuer.getTotalWounded(), canRescue);

        // 回复兵力
        isRescuer.setBingLi((short) (isRescuer.getBingLi() + canRescue));
        // 减少伤兵
        isRescuer.setTotalWounded((int) (isRescuer.getTotalWounded() - canRescue));

        // 统计该技能的治疗量
        SKillCount sKillCount = rescuer.getSkillCount().get(skillName);
        sKillCount.setRescue(sKillCount.getRescue() + canRescue);

        // 统计该武将的治疗量
        rescuer.setTotalCure(rescuer.getTotalCure() + canRescue);

        return canRescue;
    }
}
